



import bpy
from bpy.types import Operator
from 全局控制.Node.节点和插座基类.bl_UpdateNode import *
from 对象操作 import bl_对象变换帧

import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
import 全局控制.Node.插座.bl_插座基类 as 插件基类
import Core.bl_渲染层 as 渲染层


def f_set_实例物体(self, value):
	self["m_实例物体"] = value
	#print(self)

class C_体素物体组(bpy.types.PropertyGroup):
	m_Obj = bpy.props.PointerProperty(type=bpy.types.Object)





class C_SceneNode_体素物体(基类.C_SN_基类):
	bl_dname = 'bl_node_体素物体'
	bl_label = '体素物体'
	
	
	m_物体name前缀 = bpy.props.StringProperty(name='前缀')
	m_渲染层 = bpy.props.StringProperty(name='渲染层')
	m_参考物体 = bpy.props.PointerProperty(type=bpy.types.Object)
	m_是否实例 = bpy.props.BoolProperty(default=True)
	#m_是否拷贝子物体 = bpy.props.BoolProperty(default=True)
	
	m_体素物体 = bpy.props.CollectionProperty(type=C_体素物体组)
	m_渲染层名称 = bpy.props.StringProperty(default='渲染层名称')
	
	def init(self, context):
		super(C_SceneNode_体素物体, self).f_init(context)
		self.inputs.new('C_NodeSocket_N矩阵_f', name='输入坐标')
		self.inputs.new('C_NodeSocket_3f', name='输入尺寸')
		self.inputs.new('C_NodeSocket_物体', name='父对象')
		
		self.outputs.new('C_NodeSocket_物体', name='对象序列')
		

	def draw_buttons(self, context, layout):
		column = layout.column()
		column.prop(self, "m_参考物体")
		column.prop(self, "m_是否实例")
		column.prop(self, 'm_物体name前缀')
		
		if bpy.data.collections.find(self.m_渲染层) >= 0 :
			column.prop_search(self, "m_渲染层", bpy.data, "collections", text="粒子发射器组")
		else:
			布局 = column.row()
			布局.prop(self, 'm_渲染层')
			创建 = 布局.operator("node.update_node_create_collection")
			创建.m_名称 = self.m_渲染层
			
		
	'''def update(self):
		矩阵插座 = self.inputs['输入坐标']
		rut = 插件基类.f_连接到插座是否为正确类型(矩阵插座, 'C_NodeSocket_N矩阵_f')
		if rut == -1 :
			self.color = (1.0 , 0.0, 0.0)
		else:
			self.color = (0.5 , 0.5, 0.5)
	'''
	
	def f_get上一层插座(self, 当前连接):
		if 当前连接.from_node.type == 'REROUTE' :
			for 连接到的插座 in 当前连接.from_node.inputs:
				if 连接到的插座.is_linked :
					for link in 连接到的插座.links:
						return self.f_get上一层插座(link)
			
		return 当前连接
	
	def f_update物体创建(self, scene):
		if self.m_物体name前缀 == '' or self.m_参考物体 == None : return
		
		比例输出插座 = f_get上一层Output插座(self.inputs['输入尺寸'])
		if 比例输出插座 == None :
			比例 = self.inputs['输入尺寸'].f_getData()
		else:
			比例 = 比例输出插座.f_getData()

		
		父对象 = None
		if self.inputs['父对象'].is_linked:
			父对象 = self.inputs['父对象'].f_getData()[0]


		#取得上个节点矩阵数据
		输入坐标插座 = self.inputs['输入坐标']
		
		socket = f_get上一层Output插座(输入坐标插座)
		if socket == None : return

		#for socket in self.inputs:
		渲染层容器 = bpy.data.collections.find(self.m_渲染层)
		
		if socket.is_linked == False or 渲染层容器 < 0: return

		渲染层容器 = bpy.data.collections[渲染层容器]
		mesh = self.m_参考物体.data

		
		for 连接到的插座 in socket.links:
			临时物体容器 = []

			上个节点输出插座 = self.f_get上一层插座(连接到的插座)
			#print(上个节点输出插座)
			num = 上个节点输出插座.from_socket.f_getDataNum()
			if num :
				#清除以前的物体
				临时容器 = 渲染层.f_对象从容器中断开(渲染层容器)
				老数据 = len(临时容器)
				
				self.m_体素物体.clear()
				for i in range(num):
					域GUID = 上个节点输出插座.from_socket.f_getData(i)
					索引 = 域GUID[0]
					坐标 = 域GUID[1]
					name = self.m_物体name前缀 + '_' + str(索引[0])+'_'+str(索引[1])+'_'+str(索引[2])
					
					#使用备份数据
					if i >= 老数据:
						new_object = bpy.data.objects.new(name=name, object_data=mesh)
					else:
						new_object = 临时容器[i]
						new_object.data = mesh
						new_object.name = name
					#清除变换帧
					if new_object.animation_data: # and new_object.animation_data.action
						bl_对象变换帧.f_remove对象PATH曲线(new_object.animation_data.action.fcurves, ['location', 'rotation_euler', 'scale'])
						new_object.animation_data.action.fcurves.update()
						#print('重置体素变换坐标')
					
					渲染层容器.objects.link(new_object)
					# Place lamp to a specified location
					new_object.location = (坐标[0], 坐标[1], 坐标[2])
					new_object.rotation_euler = self.m_参考物体.rotation_euler
					new_object.scale = (比例[0]*0.5, 比例[1]*0.5, 比例[2]*0.5)
					new_object.parent = 父对象
					new_object.hide_viewport = False
					临时物体容器.append(new_object)
					
			输出插座 = self.outputs[0]
			输出插座.f_setData(临时物体容器)
			#print('临时物体容器 = ', 临时物体容器)
			break



	def f_update(self, 是否向下传递=False, input插座=None):
		self.f_update物体创建(bpy.context.scene)
		super(C_SceneNode_体素物体, self).f_update(是否向下传递, input插座)
		
		


class C_NODE_AddMenu_体素物体(bpy.types.Operator):
	bl_idname = 'node.global_node_object_voxel_add'
	bl_label = 'Add 体素化物体实例'
	bl_options = {'REGISTER', 'UNDO'}
	
	def execute(operator, context):
		operator.use_transform = True
		bpy.ops.node.add_node(type='C_SceneNode_体素物体', use_transform=True)
		return {'FINISHED'}



classes = (
	C_体素物体组,
	#C_ops_创建Collection,

	C_SceneNode_体素物体,
	C_NODE_AddMenu_体素物体,
	
)




def register():
	for c in classes:
		bpy.utils.register_class(c)
		

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)

	

